package com.ibeeking.found.file.rest.service.impl;

import com.ibeeking.found.common.config.prop.FileOssProp;
import com.ibeeking.found.common.utils.UrlUtils;
import com.ibeeking.found.common.utils.UserUtils;
import com.ibeeking.found.file.rest.service.ISourceService;
import com.ibeeking.found.file.service.common.bo.SourceBO;
import com.ibeeking.found.file.service.common.constants.SourceConstant;
import com.ibeeking.found.file.service.common.dos.SourceDO;
import com.ibeeking.found.file.service.common.param.SourceAddParam;
import com.ibeeking.found.file.service.common.param.SourceModifyBatch;
import com.ibeeking.found.file.service.common.param.SourceParam;
import com.ibeeking.found.file.service.common.param.SourceSetParam;
import com.ibeeking.found.file.service.common.query.SourcePageQuery;
import com.ibeeking.found.file.service.common.query.SourceQuery;
import com.ibeeking.found.file.service.common.vo.SourceVO;
import com.ibeeking.found.file.service.common.vo.SourceViewVo;
import com.ibeeking.found.file.service.mapper.SourceMapper;
import com.ibeeking.nematos.exception.BusinessException;
import com.ibeeking.nematos.utils.bean.BeanUtil;
import com.ibeeking.nematos.utils.json.JsonUtils;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.alibaba.nacos.common.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName SourceServiceImpl
 * @Description
 * @Author ibeeking
 * @Date 2021-02-05 16:17
 **/
@Service
public class SourceServiceImpl extends ServiceImpl<SourceMapper, SourceDO> implements ISourceService {

    @Resource
    private SourceMapper sourceMapper;
    @Resource
    private FileOssProp fileOssProp;

    @Override
    public List<SourceVO> list(SourceQuery sourceQuery) {
        LambdaQueryWrapper<SourceDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(SourceConstant.MODIFY_TIME.equals(sourceQuery.getRule()), SourceDO::getModifyTime)
                .orderByDesc(SourceConstant.CREATE_TIME.equals(sourceQuery.getRule()), SourceDO::getCreateTime)
                .orderByAsc(SourceConstant.NAME.equals(sourceQuery.getRule()), SourceDO::getName)
                .eq(SourceDO::getType, sourceQuery.getType())
                .eq(sourceQuery.getParentId() != null, SourceDO::getParentId, sourceQuery.getParentId())
                .like(StringUtils.isNotEmpty(sourceQuery.getName()), SourceDO::getName, sourceQuery.getName())
                .eq(StringUtils.isNotEmpty(sourceQuery.getContentType()), SourceDO::getContentType, sourceQuery.getContentType());
        List<SourceDO> sourceDOS = sourceMapper.selectList(queryWrapper);
        for (SourceDO sourceDO : sourceDOS) {
            if (StringUtils.isNotEmpty(sourceDO.getPath())) {
                sourceDO.setPath(UrlUtils.addUrlDomainName(fileOssProp.getHost(), sourceDO.getPath()));
            }
        }
        return JsonUtils.jsonToList(sourceDOS, SourceVO.class);
    }

    @Override
    public Page<SourceVO> pageList(SourcePageQuery sourcePageQuery) {
        LambdaQueryWrapper<SourceDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(sourcePageQuery.getShopId() != null, SourceDO::getShopId, sourcePageQuery.getShopId())
                .eq(sourcePageQuery.getParentId() != null, SourceDO::getParentId, sourcePageQuery.getParentId())
                .eq(SourceDO::getType, sourcePageQuery.getType())
                .eq(SourceDO::getMerchantsBusiness, sourcePageQuery.getMerchantsBusiness())
                .eq(StringUtils.isNotEmpty(sourcePageQuery.getContentType()), SourceDO::getContentType, sourcePageQuery.getContentType())
                .orderByDesc(SourceConstant.MODIFY_TIME.equals(sourcePageQuery.getRule()), SourceDO::getModifyTime)
                .orderByDesc(SourceConstant.CREATE_TIME.equals(sourcePageQuery.getRule()), SourceDO::getCreateTime)
                .orderByAsc(SourceConstant.NAME.equals(sourcePageQuery.getRule()), SourceDO::getName)
                .like(StringUtils.isNotEmpty(sourcePageQuery.getName()), SourceDO::getName, sourcePageQuery.getName())
                .like(StringUtils.isNotEmpty(sourcePageQuery.getRemark()), SourceDO::getRemark, sourcePageQuery.getRemark());
        Page page = new Page(sourcePageQuery.getPageNum(), sourcePageQuery.getPageSize());
        Page<SourceDO> pages = sourceMapper.selectPage(page, queryWrapper);
        Page<SourceVO> goodsSourceVOPage = BeanUtil.convertPage(pages, SourceVO.class);
        Integer count = sourceMapper.selectCount(queryWrapper);
        for (SourceVO sourceVO : goodsSourceVOPage.getRecords()) {
            if (StringUtils.isNotEmpty(sourceVO.getPath())) {
                sourceVO.setPath(UrlUtils.addUrlDomainName(fileOssProp.getHost(), sourceVO.getPath()));
            }
            sourceVO.setAllCount(count);
        }
        return goodsSourceVOPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(SourceAddParam goodsSourceParam) {
        for (SourceSetParam sourceSetParam : goodsSourceParam.getSources()) {
            SourceDO sourceDO = BeanUtil.convertBean(goodsSourceParam, SourceDO.class);
            sourceDO.setCreateBy(UserUtils.getUserId());
            sourceDO.setCreateTime(LocalDateTime.now());
            sourceDO.setModifyTime(LocalDateTime.now());
            sourceDO.setPath(sourceSetParam.getPath());
            sourceDO.setName(sourceSetParam.getName());
            sourceDO.setRemark(sourceSetParam.getRemark());
            //parentId为1 为 未分组
            if (sourceDO.getParentId() == 1) {
                sourceDO.setParentId(SourceConstant.parentId);
            }
            sourceMapper.insert(sourceDO);
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean modify(SourceParam sourceParam) {
        LambdaQueryWrapper<SourceDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SourceDO::getName, sourceParam.getName());
        List<SourceDO> sourceDOS = sourceMapper.selectList(queryWrapper);
        if (CollectionUtils.isNotEmpty(sourceDOS)) {
            throw new BusinessException("素材名称不能重复");
        }
        SourceDO sourceDO = BeanUtil.convertBean(sourceParam, SourceDO.class);
        sourceDO.setPath(UrlUtils.removeMallUrlDomainName(fileOssProp.getHost(), sourceDO.getPath()));
        sourceDO.setModifyBy(UserUtils.getUserId());
        sourceDO.setModifyTime(LocalDateTime.now());
        return sourceMapper.updateById(sourceDO) > 0;
    }

    @Override
    public SourceViewVo view(Long id) {
        SourceDO sourceDO = sourceMapper.selectById(id);
        sourceDO.setPath(UrlUtils.addUrlDomainName(fileOssProp.getHost(), sourceDO.getPath()));
        ArrayList<String> list = new ArrayList<>();
        SourceViewVo sourceViewVo = BeanUtil.convertBean(sourceDO, SourceViewVo.class);
        if (sourceDO.getParentId() == 0) {
            list.add(id + "");
        } else {
            SourceDO sourceDO1 = sourceMapper.selectById(sourceDO.getParentId());
            if (sourceDO1 != null) {
                list.add(sourceDO1.getParentId() + "");
            }
            list.add(sourceDO.getParentId() + "");
        }
        sourceViewVo.setParentIds(list);
        return sourceViewVo;
    }


    @Override
    public Boolean del(Long id) {
        return sourceMapper.deleteById(id) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean delBatchIds(List<Long> ids) {
        Boolean flag = false;
        List<List<Long>> parts = Lists.partition(ids, 1000);
        for (List<Long> part : parts) {
            flag = sourceMapper.deleteBatchIds(part) > 0;
        }
        return flag;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean modifyBatchIds(SourceModifyBatch sourceModifyBatch) {
        //parentID为1移动到未分组
        if (sourceModifyBatch.getParentId() == 1) {
            sourceModifyBatch.setParentId(SourceConstant.parentId);
        }
        LambdaQueryWrapper<SourceDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(SourceDO::getId, sourceModifyBatch.getIds());
        SourceDO sourceDO = new SourceDO();
        sourceDO.setParentId(sourceModifyBatch.getParentId());
        sourceDO.setModifyTime(LocalDateTime.now());
        return sourceMapper.update(sourceDO, queryWrapper) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void modifyParentId(Long parentId) {
        LambdaQueryWrapper<SourceDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SourceDO::getParentId, parentId);
        List<SourceDO> sourceDOS = sourceMapper.selectList(queryWrapper);
        for (SourceDO sourceDO : sourceDOS) {
            sourceDO.setParentId(SourceConstant.parentId);
            sourceDO.setModifyTime(LocalDateTime.now());
            sourceMapper.updateById(sourceDO);
        }
    }

    @Override
    public Integer listCountByParentIdAndType(SourceBO sourceBO) {
        LambdaQueryWrapper<SourceDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(sourceBO.getShopId() != null, SourceDO::getShopId, sourceBO.getShopId())
                .eq(SourceDO::getMerchantsBusiness, sourceBO.getMerchantsBusiness())
                .eq(SourceDO::getParentId, sourceBO.getId())
                .eq(SourceDO::getType, sourceBO.getType());
        return sourceMapper.selectCount(queryWrapper);
    }
}